home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
shells
/
cshel500
/
part04
/
comm1.c
next >
Wrap
C/C++ Source or Header
|
1991-03-03
|
30KB
|
1,340 lines
/*
* COMM1.C
*
* Matthew Dillon, August 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
* Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
* Version 5.00L by Urban Mueller 17-Feb-91
*
*/
#include "shell.h"
/* comm1.c */
static void display_file(char *filestr);
static char *myfgets(char *buf, int buflen, struct __stdio *file);
static int search_file(char *s);
static int quicksearch(char *name, int nocasedep, char *pattern);
static int rm_file(char *file);
static void setsystemtime(struct DateStamp *ds);
static int found( char *lstart, int lnum, int loffs, char *name, char left );
static void recurse(char *name, int (*action)(char *));
static void recurse2( char *name, void (*action)(FIB *));
extern int has_wild;
int
do_sleep( void )
{
int i;
if (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i--) Delay(50);
return 0;
}
int
do_protect( void )
{
static char flags[]="DEWRAPSH";
char *s, *p;
long setmask=0, clrmask=0xFF, mask;
int i, mode=0, stat;
struct DPTR *dp;
for (s=strupr(av[--ac]); *s; s++) {
if (*s=='=') { mode=0; continue; }
if (*s=='+') { mode=1; clrmask=FIBF_ARCHIVE; continue; }
if (*s=='-') { mode=2; clrmask=FIBF_ARCHIVE; continue; }
if (p=index(flags, *s)) {
if( mode==0 ) setmask|= 1<<(p-flags), clrmask=0xFF;
if( mode==1 ) setmask|= 1<<(p-flags);
if( mode==2 ) clrmask|= 1<<(p-flags);
} else
ierror(av[ac],500);
}
for (i=1; i<ac; i++) {
if( (dp=dopen(av[i],&stat))) {
mask = dp->fib->fib_Protection ^ 0x0F;
mask&=~clrmask;
mask|= setmask;
dclose(dp);
if( !SetProtection( av[i], mask ^ 0x0F))
pError(av[i]);
} else
pError(av[i]);
}
return 0;
}
int
do_filenote( void )
{
struct DPTR *dp;
char *note;
int i, stat;
if( options&1 ) {
for( i=1; i<ac && !dobreak(); i++ )
if( dp=dopen( av[i], &stat )) {
printf( "%-12s %s\n", av[i],dp->fib->fib_Comment );
dclose( dp );
}
} else {
note=av[--ac];
for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
}
return 0;
}
int
do_cat( void )
{
FILE *fi;
int lctr, i;
char buf[256];
prepscroll(0);
if (ac<=1) {
if (has_wild) { printf("No files matching\n"); return 20; }
lctr=0;
while (fgets(buf,256,stdin) &&
!dobreak()) {
if (options) printf("%4d ",++lctr);
quickscroll();
fputs(buf,stdout);
}
} else {
for (i=1; i<ac; i++)
if (fi = fopen (av[i], "r")) {
lctr=0;
while (fgets(buf,256,fi) && !dobreak()) {
if (options&1) printf("%4d ",++lctr);
quickscroll();
printf("%s",buf);
}
fclose (fi);
} else
pError(av[i]);
}
return 0;
}
void
get_drives(char *buf)
{
struct DirectoryEntry *de_head=NULL, *de;
buf[0]=0;
AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
for(de=de_head; de; de=de->de_Next) {
if( buf[0] )
strcat( buf, "\240" );
strcat( buf, de->de_Name );
}
FreeDAList(de_head);
}
static char infobuf[100];
static char namebuf[12];
char *
drive_name( char *name )
{
struct DirectoryEntry *de_head=NULL, *de;
struct MsgPort *proc=DeviceProc( name );
strcpy( namebuf, name );
AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
for(de=de_head; de; de=de->de_Next)
if( DeviceProc( de->de_Name) == proc )
strcpy( namebuf, de->de_Name );
FreeDAList(de_head);
return namebuf;
}
int
do_info( void )
{
struct DirectoryEntry *de_head=NULL, *de;
int i;
puts("Unit Size Bytes Used Blk/Byt-Free Full Errs Status Name");
Myprocess->pr_WindowPtr = (APTR)(-1);
if( ac==1 ) {
AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
for(de=de_head; de; de=de->de_Next)
oneinfo( de->de_Name, 0);
FreeDAList(de_head);
} else {
for( i=1; i<ac; i++ )
oneinfo( drive_name( av[i] ), 0 );
}
Myprocess->pr_WindowPtr = (APTR) o_noreq;
return 0;
}
char *
oneinfo( char *name, int mode )
{
BPTR lock;
struct InfoData *info;
long size, free, freebl, blocks;
char *p, buf[130], *state=" ";
char *fmt="%s\240%s\240%d\240%d\240%d\240%s\240%d%%\240%d\240%s\240%s";
infobuf[0]=0;
if( !name ) name="";
strcpy(infobuf,"0");
info=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
if (lock=Lock(name,ACCESS_READ)) {
if (Info(lock, info)) {
PathName(lock, buf, 128L);
if (p=index(buf,':')) *p = '\0';
size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock);
freebl= (info->id_NumBlocks-info->id_NumBlocksUsed);
free = freebl * info->id_BytesPerBlock;
switch(info->id_DiskState) {
case ID_WRITE_PROTECTED: state="Read Only "; break;
case ID_VALIDATED: state="Read/Write"; break;
case ID_VALIDATING: state="Validating"; break;
}
blocks=info->id_NumBlocks;
if( mode==0 ) fmt="%-7s%5s%6d%7d%7d %5s%4d%%%4d %s %s\n";
sprintf(infobuf,fmt,
name,
itok( size ),
info->id_BytesPerBlock,
info->id_NumBlocksUsed,
freebl,
itok( free ),
(blocks) ? (info->id_NumBlocksUsed * 100)/blocks : 0,
info->id_NumSoftErrors,
state,
buf);
if( mode==2 ) sprintf( infobuf, "%d", free );
if( mode==3 ) sprintf( infobuf, "%d", freebl );
if( mode==4 ) sprintf( infobuf, "%s", itok( free ));
if( mode==5 ) sprintf( infobuf, "%s:", buf );
} else
pError (name);
UnLock(lock);
} else {
if ( mode==1 ) sprintf( infobuf, "%s\240No disk present", name );
else if( mode==0 ) sprintf( infobuf, "%-7s No disk present\n",name);
else if( mode==5 ) sprintf( infobuf, "" );
else sprintf( infobuf, "0" );
}
if( mode==0 ) printf( "%s",infobuf);
FreeMem(info,sizeof(struct InfoData));
return infobuf;
}
/* things shared with display_file */
#define DIR_SHORT 0x1
#define DIR_FILES 0x2
#define DIR_DIRS 0x4
#define DIR_NOCOL 0x8
#define DIR_NAMES 0x10
#define DIR_HIDE 0x20
#define DIR_LEN 0x40
#define DIR_TIME 0x80
#define DIR_BACK 0x100
#define DIR_UNIQ 0x200
#define DIR_IDENT 0x400
#define DIR_CLASS 0x800
#define DIR_QUIET 0x1000
#define DIR_AGE 0x2000
#define DIR_VIEW 0x4000
#define DIR_NOTE 0x8000
static BPTR lastlock;
static int filecount, col, wwidth;
static long bytes, blocks;
/* the args passed to do_dir will never be expanded */
extern expand_err;
extern int w_width;
static struct DateStamp Stamp;
int
do_dir( void )
{
int i=1, c, eac, reverse, nump=ac, retcode=0;
char **eav, **av1, **av2, inter=interactive();
int (*func)(), ac1, ac2;
if( options&DIR_CLASS ) options|=DIR_IDENT;
if( ac == i) ++nump, av[i]="";
if( !(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
if( options&DIR_UNIQ) {
if( ac-i!=2 ) { show_usage(NULL); return 20; }
i=0, nump=3;
}
if( options&DIR_AGE )
DateStamp( &Stamp );
col = filecount = bytes = blocks = 0L;
lastlock=NULL;
wwidth=77;
if( inter ) printf( "\033[?7l" ), wwidth=w_width; /* end of line wrap off */
prepscroll(0);
for( ; i<nump && !CHECKBREAK(); ++i ) {
if( options&DIR_UNIQ ) {
switch( i ) {
case 0: av1=expand( av[ac-2], &ac1 );
av2=expand( av[ac-1], &ac2 );
eav=without( av1, ac1, av2, ac2, &eac, 1 );
break;
case 1: printf("\nCommon files\n");
eav=and( av1, ac1, av2, ac2, &eac, 1 );
break;
case 2: printf("\n");
eav=without( av2, ac2, av1, ac1, &eac, 1 );
break;
}
col = filecount = bytes = blocks = 0L;
lastlock=NULL;
} else if (!(eav = expand(av[i], &eac)) && expand_err) {
pError(av[i]);
retcode=5;
continue;
}
reverse= ( options&DIR_BACK ) ? 1 : 0;
func=cmp;
if( options & DIR_TIME) func=datecmp;
if( options & DIR_LEN ) func=sizecmp;
if( options & DIR_CLASS)func=classcmp;
DirQuickSort(eav, eac, func, reverse);
for(c=0; c<eac && !CHECKBREAK(); ++c) {
if( options & DIR_HIDE ) {
char *b=BaseName(eav[c]);
int l=strlen(b)-5;
struct file_info *info =
(struct file_info *)(eav[c]-sizeof(struct file_info));
if(*b=='.'|| (l>=0 && !strcmp(b+l,".info"))||(info->flags&128))
continue;
}
if (options & DIR_NAMES)
puts(eav[c]);
else
display_file(eav[c]);
}
if (col) { quickscroll(); printf("\n"); col=0; }
if (options&DIR_UNIQ || (filecount>1 && i==nump-1)) {
blocks += filecount; /* account for dir blocks */
quickscroll();
printf(" %ld Blocks, %s Bytes used in %d files\n",
blocks, itoa(bytes), filecount);
}
if( options&DIR_UNIQ )
free(eav);
else
free_expand (eav);
if (lastlock) UnLock(lastlock), lastlock=0;
}
if (lastlock) UnLock(lastlock), lastlock=0;
if( options&DIR_UNIQ )
free_expand( av1 ), free_expand( av2 );
if( inter ) printf( "\033[?7h" ); /* end of line wrap off */
return retcode;
}
static void
display_file( char *filestr )
{
int isadir,slen;
char sc, *base, buf[130];
struct file_info *info;
BPTR thislock;
base=BaseName(filestr);
sc = *base;
*base = '\0';
thislock=Lock(filestr,SHARED_LOCK);
/* if (thislock==NULL) return; */
if (lastlock==NULL || CompareLock(thislock,lastlock)) {
/* struct InfoData *id=AllocMem( sizeof(struct InfoData), 0); */
if (col) { quickscroll(); printf("\n"); col=0; }
quickscroll();
PathName(thislock, buf, 128L);
/* Info( thislock, id ); */
printf("Directory of %s\n", buf );
/*itok((id->id_NumBlocks-id->id_NumBlocksUsed)*id->id_BytesPerBlock));*/
/* FreeMem( id, sizeof(struct InfoData)); */
if (lastlock) UnLock(lastlock);
lastlock=thislock;
} else
UnLock(thislock);
*base = sc;
if((slen = strlen(base)+1) & 1 ) ++slen;
info = (struct file_info *)(filestr - sizeof(struct file_info));
isadir = info->size<0;
if (!(((options & DIR_FILES) && !isadir) ||
((options & DIR_DIRS) && isadir)))
return;
if (isadir && !(options & DIR_NOCOL)) printf (o_hilite);
if (options & DIR_SHORT) {
slen= (slen>18) ? 37 : 18;
if (col && col+slen>=wwidth )
{ quickscroll(); printf("\n"); col = 0; }
printf(" %-*s",slen,base);
col+= ++slen;
} else {
quickscroll();
printf(" %-24s %s \n",base,formatfile(info));
}
if (isadir && !(options & DIR_NOCOL))
printf(o_lolite);
if(info->size>0)
bytes += info->size;
blocks += info->blocks;
filecount++;
}
/* will have either of these formats:
*
* fullfilename'\0'hsparwed <Dir> DD-MMM-YY HH:MM:SS\n'\0'
* fullfilename'\0'hsparwed NNNNNNN NNNN DD-MMM-YY HH:MM:SS\n'\0'
* 1111111111222222222233333333334 4 4
* 01234567890123456789012345678901234567890 1 2
*/
static char linebuf[140];
static long dlen, dblocks;
static void
count( FIB *fib )
{
dlen+=fib->fib_Size;
dblocks+=fib->fib_NumBlocks+1;
}
char *
formatfile( struct file_info *info)
{
char *str=linebuf, *class, *t;
int i, stat;
if( options & DIR_NOTE ) {
struct DPTR *dp;
if( dp=dopen( (char *)(info+1), &stat )) {
strcpy( str, dp->fib->fib_Comment );
dclose( dp );
}
return linebuf;
}
*str++= info->flags & 1<<30 ? 'c' : '-';
for (i=7; i>=0; i--)
*str++ = ((info->flags & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
if (info->size >= 0)
sprintf(str,options&DIR_QUIET?" %7ld ":" %7ld %4ld ",
info->size, info->blocks);
else
strcpy(str,options&DIR_QUIET?" <Dir> ":" <Dir> ");
str+=strlen(str);
if( options&DIR_VIEW && info->size<0 ) {
dlen=dblocks=0;
recurse2( (char *)(info+1),count);
sprintf( str, "%10s",itoa(dlen));
info->size=dlen; info->blocks=dblocks;
} else if( options&DIR_IDENT ) {
if( *info->class!=1 )
strcpy(str,info->class);
else if( class=getclass((char *)(info+1)))
if( t=index(strncpy(str,class,40),0xA0) )
*t=0;
} else if( options&DIR_AGE) {
long mins=0;
if( Stamp.ds_Days!=0 ) {
mins =Stamp.ds_Days*1440 + Stamp.ds_Minute;
mins-=info->date.ds_Days*1440 + info->date.ds_Minute;
}
if( mins>=0 )
sprintf(str,"%4d %02d:%02d",mins/1440,mins/60%60,mins%40);
else
sprintf(str,"Future");
} else if( !(options&DIR_VIEW) )
strcat(str,dates(&info->date));
return linebuf;
}
int
do_quit( void )
{
if (Src_stack) {
Quit = 1;
return(do_return());
}
main_exit(0);
return 0;
}
int
do_echo( void )
{
char *args=compile_av(av,1,ac,' ',0);
fprintf( (options&2)?stderr:stdout, (options&1)?"%s":"%s\n",args );
free(args);
return 0;
}
static int
breakcheckd(void)
{
int ret=!o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_D;
SetSignal(0L, SIGBREAKF_CTRL_D);
if( ret )
fprintf(stderr,"^D\n");
return ret;
}
/* gets a line from file, joining two lines if the first ends in '\' */
static char *
myfgets(char *buf, int buflen, FILE *file)
{
char *bufptr=buf, *limit=buf+buflen;
do {
if (fgets(bufptr, limit-bufptr, file)==NULL) {
if (bufptr != buf)
fprintf(stderr,"Source: file ends in '\\'\n");
return NULL;
}
bufptr = bufptr+strlen(bufptr)-2;
} while (*bufptr=='\\');
return buf;
}
int
do_source( char *str )
{
FILE *fi;
char *buf;
int len;
if (Src_stack == MAXSRC) {
ierror(NULL,217);
return -1;
}
if ((fi = fopen (av[1], "r")) == 0)
{ pError(av[1]); return -1; }
buf=malloc(512);
set_var(LEVEL_SET, v_passed, next_word(next_word(str)));
++H_stack;
Src_pos[Src_stack] = 0;
Src_base[Src_stack] = fi;
Src_if[Src_stack]=If_stack;
++Src_stack;
while (myfgets (buf, 512, fi) && !dobreak() && !breakcheckd()) {
len = strlen(buf);
if(buf[len-1]=='\n')
buf[len-1] = '\0';
Src_pos[Src_stack - 1] += len;
if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
exec_command (buf);
}
--H_stack;
--Src_stack;
if( If_stack>Src_if[Src_stack] )
If_stack=Src_if[Src_stack], disable=If_stack && If_base[If_stack-1];
if (forward_goto) ierror(NULL,501);
forward_goto = 0;
unset_level(LEVEL_SOURCE + Src_stack);
unset_var(LEVEL_SET, v_gotofwd);
unset_var(LEVEL_SET, v_passed);
free(buf);
fclose (fi);
return 0;
}
/* set process cwd name and $_cwd, if str != NULL also print it. */
int
do_pwd( char *str )
{
char pwd[130];
PathName(Myprocess->pr_CurrentDir, pwd, 128L);
if (str) puts(pwd);
set_var(LEVEL_SET, v_cwd, pwd);
/* put the current dir name in our CLI task structure */
CtoBStr(pwd, Mycli->cli_SetName, 128L);
return 0;
}
/*
* CD
*
* CD(str, 0) -do CD operation.
*
*/
extern int qcd_flag;
static char lastqcd[80];
static lastoffs;
int
do_cd( char *str )
{
BPTR oldlock, filelock;
FILE *file;
char buf[100], *old;
int i=1, repeat;
if( options & 1 ) {
if( !(file=fopen( o_csh_qcd, "w" )))
{ fprintf(stderr,"Can't open output\n"); return 20; }
for( ; i<ac && !breakcheck(); i++ ) {
fprintf(file,"%s\n",av[i]);
strcpy(buf,av[i]);
appendslash( buf );
expand_all( buf, file );
}
fclose(file);
return 0;
}
str= ( has_wild && ac>=2 ) ? av[1] : next_word(str);
if (!strcmp("..",str)) str="/";
if( !*str ) {
printf("%s\n", get_var( LEVEL_SET, v_cwd ));
return 0;
}
if (filelock=Lock(str,ACCESS_READ)) {
lastqcd[0]=0;
if (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
} else {
repeat= !strncmp( lastqcd, str, 79 );
strncpy( lastqcd, str, 79);
if( !quick_cd( buf, av[i], repeat) )
{ fprintf(stderr,"Object not found %s\n",str); return 20; }
if (!(filelock=Lock(buf,ACCESS_READ)))
{ pError(buf); return 20; }
}
if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
if( !(old=get_var(LEVEL_SET, v_cwd)) )
old="";
set_var(LEVEL_SET, v_lcd, old);
do_pwd(NULL);
return 0;
}
char *
quick_cd( char *buf, char *name, int repeat )
{
qcd_flag=repeat ? 2 : 1;
strcpy(buf,name);
if( quicksearch( o_csh_qcd, 1, buf)!=2 )
return NULL;
return buf;
}
int
do_mkdir( void )
{
int i;
BPTR lock;
for (i=1; i<ac; ++i) {
if (exists(av[i]))
ierror(av[i],203);
else if (lock=CreateDir(av[i]))
UnLock (lock);
else
pError(av[i]);
}
return 0;
}
int
do_mv( void )
{
char *dest, buf[256];
int dirflag, i;
dirflag=isdir(dest=av[--ac]);
if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
for (i=1; i<ac; ++i) {
strcpy(buf, dest);
if (dirflag) TackOn(buf, BaseName(av[i]));
if (Rename(av[i], buf)==0)
{ pError(av[i]); return -1; }
else
clear_archive_bit( buf );
}
return 0;
}
static int dirstoo;
int
all_args( int (*action)(char *str), int dirsflag )
{
int i;
dirstoo=dirsflag;
for ( i=1; i<ac && !dobreak(); ++i)
if (isdir(av[i])) {
if (options & 1) recurse(av[i], action);
else if (dirstoo) (*action)(av[i]);
} else
(*action)(av[i]);
return 0;
}
char *searchstring;
char docr;
#define SEARCH_REC 1
#define SEARCH_CASE 2
#define SEARCH_WILD 4
#define SEARCH_NUM 8
#define SEARCH_EXCL 16
#define SEARCH_QUIET 32
#define SEARCH_VERB 64
#define SEARCH_BIN 128
#define SEARCH_FILE 256
#define SEARCH_ABORT 512
#define SEARCH_LEFT 1024
#define SEARCH_ONLY 2048
static int abort_search;
static char lowbuf[256], file_name, file_cr;
static int
search_file( char *s )
{
FILE *fopen(), *fi;
char *p, *q;
int nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
char buf[256], searchit[120], first, left;
if( abort_search )
return 0;
nocasedep=!(options & SEARCH_CASE);
lctr= docr= file_name= file_cr= 0;
if (!(options & (SEARCH_QUIET|SEARCH_FILE)))
if( options & SEARCH_VERB )
printf("Examining %s...\n",s);
else
printf("\015Examining %s... ",s), docr=1;
strcpy(searchit,searchstring);
if (options & SEARCH_WILD) strcat(searchit,"\n");
len=strlen(searchit);
if (nocasedep) strupr(searchit);
first=*searchit;
if( strcmp("STDIN",s) && !(options&SEARCH_WILD) && !excl ||
options&SEARCH_BIN )
if( quicksearch(s,nocasedep,searchit) )
return 0;
if( options&SEARCH_BIN )
{ fprintf(stderr,"Out of memory\n"); return 20; }
fi = strcmp("STDIN",s) ? fopen(s,"r") : stdin;
if (fi==NULL) { pError(s); return 20; }
prepscroll(0);
while (fgets(buf,256,fi) && !dobreak()) {
lctr++; left=1;
if (options & SEARCH_WILD)
yesno=compare_ok(searchit, buf, options&SEARCH_CASE);
else {
if (nocasedep) {
strcpy(lowbuf,buf);
strupr(lowbuf);
p=lowbuf;
} else
p=buf;
q=p;
while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
yesno= (p!=NULL);
left = --p - q;
}
if( yesno ^ excl )
if(!(options&SEARCH_ONLY)|| !isalphanum(p[-1])&&!isalphanum(p[len]))
if( found(buf, lctr, 0, s, left ) )
break;
}
if (fi!=stdin) fclose (fi);
if( file_cr ) printf("\n");
return 0;
}
int qcd_flag, qcd_offs;
static int
quicksearch( char *name, int nocasedep, char *pattern )
{
int i, ptrn=strlen(pattern);
char ut[256], *buffer, *lend;
char *uptab=ut, *get, c, *lpos, *lstart;
int len, lnum, qcd=qcd_flag, repeat=(qcd==2 && qcd_offs!=0);
int sofar, got;
BPTR fh;
#ifdef AZTEC_C
while(0) while(0) c=c=0, uptab=uptab=ut, get=get=NULL;
#endif
qcd_flag=0;
if( !(fh=Open(name,MODE_OLDFILE))) {
i=(long)IoErr(), docr=0;
printf("\n");
ierror(name,i);
return 1;
}
len=filesize( name );
if( !(buffer=(void *)malloc(len+2))) { Close(fh); return 0; }
sofar=0;
do {
got=Read( fh, (char *)buffer+sofar, 60000);
sofar+=got;
} while( got==60000 );
Close( fh);
if( sofar != len ) { pError(pattern); return 1; }
if( nocasedep )
strupr( pattern );
if( !qcd )
prepscroll(0);
for( i=0; i<256; i++ ) uptab[i]=i;
if( nocasedep ) for( i='a'; i<='z'; i++ ) uptab[i]=i-'a'+'A';
retry:
c=*pattern, buffer[len]=c, buffer[len+1]=c;
get= (qcd==2) ? buffer+qcd_offs : buffer;
if( qcd==1 ) qcd_offs=0;
lpos=lstart=buffer, lnum=1;
for( ;; ) {
do ; while( uptab[*get++]!=c );
if( --get>=buffer + len )
break;
for( i=1; i<ptrn; i++ )
if( uptab[get[i]]!=pattern[i] )
break;
if( i==ptrn ) {
for( ;lpos<get; lpos++ )
if( *lpos=='\n' )
lstart=lpos+1, lnum++;
for( lend=lstart+1; *lend!='\n'; lend++ ) ;
if( qcd ) {
if( get[-1]==':' || get[-1]=='/' ||
lpos==lstart && lend[-1]==':' ) {
char *tmp;
for( tmp=get+ptrn; *tmp&& *tmp!='\n'&& *tmp!='/'; tmp++ );
if( *tmp!='/' ) {
*lend=0;
strncpy(pattern,lstart,79);
qcd_offs=lend-buffer;
free( buffer );
return 2;
}
} else
lend=lpos+1;
} else {
*lend=0;
if(!(options&SEARCH_ONLY) ||
!isalphanum(lpos[-1])&&!isalphanum(lpos[ptrn]))
if(found(lstart, lnum, get-buffer, name, lpos==lstart ))
break;
*lend='\n';
}
get=lend+1;
} else
get++;
}
if( repeat ) { repeat=0; qcd_offs=0; goto retry; }
if( file_cr ) { printf("\n"); quickscroll(); }
free( buffer );
return 1;
}
static int
found( char *lstart, int lnum, int loffs, char *name, char left )
{
int fileabort=0;
if ( docr )
{ quickscroll(); printf("\n"); docr=0; }
if( (options&SEARCH_LEFT) && !left)
return 0;
if( options&SEARCH_FILE ) {
file_cr=1;
if( !file_name )
printf("%s",name), file_name=1;
if( options&SEARCH_NUM )
fileabort=1;
else
printf(" %d",lnum);
} else if( options & SEARCH_BIN ) {
if (!(options & SEARCH_NUM))
printf("Byte offset %d\n",loffs);
else
printf("%d\n",loffs);
quickscroll();
} else {
if (!(options & SEARCH_NUM))
printf("%4d ",lnum);
printf((lstart[strlen(lstart)-1]=='\n')?"%s":"%s\n",lstart);
quickscroll();
}
abort_search= options&SEARCH_ABORT;
return dobreak() || fileabort || abort_search;
}
int
do_search( void )
{
if( Cout_name ) options |= SEARCH_VERB;
abort_search=0;
searchstring=av[--ac];
all_args(search_file, 0);
if(docr) printf("\n"),docr=0;
return 0;
}
static int
rm_file(char *file)
{
if ( file[strlen(file)-1]=='/' ) file[strlen(file)-1]=0;
if (has_wild) printf(" %s...",file);
if (options & 2) SetProtection(file,0L);
if (!DeleteFile(file))
{ pError (file); return 20; }
else if (has_wild)
printf("Deleted\n");
return 0;
}
int
do_rm( void )
{
all_args( rm_file, 1);
return 0;
}
static void
recurse(char *name, int (*action)(char *))
{
BPTR lock, cwd;
FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
char *namecopy=malloc(256);
if (name[0] =='\0') return;
namecopy[0]=0;
if (lock=Lock(name,ACCESS_READ)) {
cwd =CurrentDir(lock);
if (Examine(lock, fib))
while (ExNext(lock, fib) && !CHECKBREAK()) {
if (*namecopy)
{ (*action)(namecopy); namecopy[0]=0; }
if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
else strcpy(namecopy,fib->fib_FileName);
}
if (*namecopy) (*action)(namecopy);
UnLock(CurrentDir(cwd));
if (dirstoo) (*action)(name);
} else
pError(name);
free(namecopy);
FreeMem(fib, (long)sizeof(FIB));
}
static void
recurse2( char *name, void (*action)(FIB *))
{
BPTR lock, cwd;
FIB *fib=(FIB *)AllocMem(sizeof(FIB),MEMF_PUBLIC);
if (lock=Lock(name,ACCESS_READ)) {
cwd =CurrentDir(lock);
if (Examine(lock, fib))
while (ExNext(lock, fib) && !CHECKBREAK()) {
(*action)(fib);
if (fib->fib_DirEntryType>=0)
recurse2(fib->fib_FileName,action);
}
UnLock(CurrentDir(cwd));
}
FreeMem(fib, sizeof(FIB));
}
int
do_history( void )
{
struct HIST *hist;
int i = H_tail_base;
int len = (av[1]) ? strlen(av[1]) : 0;
for (hist = H_tail; hist && !dobreak(); hist = hist->prev, i++)
if (len == 0 || !strncmp(av[1], hist->line, len))
printf("%3d %s\n", i, hist->line);
return 0;
}
int
do_mem( void )
{
static long clast, flast;
long cfree, ffree;
char *desc="Free";
Forbid();
cfree = AvailMem (MEMF_CHIP);
ffree = AvailMem (MEMF_FAST);
Permit();
if( options&8 ) {
clast=cfree, flast=ffree;
return 0;
}
if( options&16 )
cfree=clast-cfree, ffree=flast-ffree, desc="Used";
if( options&4 ) {
if ( options & 1 ) printf("%ld\n",cfree);
else if( options & 2 ) printf("%ld\n",ffree);
else printf("%ld\n",cfree+ffree);
} else {
if ( options & 1 ) printf("Free CHIP memory %s\n",itoa(cfree));
else if( options & 2 ) printf("Free FAST memory %s\n",itoa(ffree));
else {
if(ffree) {
printf("FAST memory: %s\n",itoa(ffree));
printf("CHIP memory: %s\n",itoa(cfree));
}
printf("Total %s: %s\n",desc,itoa(cfree+ffree));
}
}
return 0;
}
int
do_forline( void )
{
char vname[33], buf[256], *cstr;
int lctr;
FILE *f;
strcpy(vname,av[1]);
f=fopen(av[2],"r");
if (f==NULL) pError(av[2]);
lctr=0;
++H_stack;
cstr = compile_av (av, 3, ac, ' ', 0);
while (fgets(buf,256,f) && !dobreak()) {
buf[strlen(buf)-1]='\0'; /* remove CR */
lctr++;
set_var(LEVEL_SET, vname, buf);
sprintf(buf,"%d",lctr);
set_var(LEVEL_SET, v_linenum, buf);
exec_command(cstr);
}
fclose(f);
--H_stack;
free (cstr);
unset_var (LEVEL_SET, vname);
unset_var (LEVEL_SET, v_linenum);
return 0;
}
int
do_fornum( void )
{
char vname[33], buf[16];
int n1, n2, step, i=1, verbose;
char *cstr;
verbose=(options & 1);
strcpy(vname,av[i++]);
n1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
n2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
if (options & 2) {
step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
} else
step=1;
++H_stack;
cstr = compile_av (av, i, ac, ' ', 0);
for (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) {
if (verbose) fprintf(stderr, "fornum: %d\n", i);
sprintf(buf,"%d",i);
set_var (LEVEL_SET, vname, buf);
exec_command(cstr);
}
--H_stack;
free (cstr);
unset_var (LEVEL_SET, vname);
return 0;
}
/*
* foreach var_name ( str str str str... str ) commands
* spacing is important (unfortunately)
*
* ac=0 1 2 3 4 5 6 7
* foreach i ( a b c ) echo $i
* foreach i ( *.c ) "echo -n "file ->";echo $i"
*/
int
do_foreach( void )
{
int cstart, cend;
char *cstr, **fav, vname[33];
int i=1, verbose;
verbose=(options & 1);
strcpy(vname, av[i++]);
if (*av[i] == '(') i++;
cstart = i;
while (i<ac && *av[i] != ')') i++;
if (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
++H_stack;
cend = i;
fav = (char **)malloc(sizeof(char *) * (ac));
cstr = compile_av (av, cend + 1, ac, ' ', 0);
for (i = cstart; i < cend; ++i) fav[i] = av[i];
for (i = cstart; i<cend && !CHECKBREAK(); ++i) {
set_var (LEVEL_SET, vname, fav[i]);
if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
exec_command(cstr);
}
--H_stack;
free (fav);
free (cstr);
unset_var (LEVEL_SET, vname);
return 0;
}
int
do_forever( char *str )
{
int rcode = 0;
char *ptr = next_word( str );
++H_stack;
for (;;) {
if (CHECKBREAK()) { rcode = 20; break; }
if (exec_command (ptr) < 0) {
str = get_var(LEVEL_SET, v_lasterr);
rcode = (str) ? atoi(str) : 20;
break;
}
}
--H_stack;
return rcode;
}
extern struct IntuitionBase *IntuitionBase;
int
do_window( void )
{
long x=-1, y=-1, w=-1, h=-1, maxwidth, maxheight, arg[5];
int i;
if(options & 32) {
struct Screen *scrn;
struct Window *window;
char buf[80];
buf[40]=0;
for (scrn=IntuitionBase->FirstScreen; scrn; scrn=scrn->NextScreen) {
buf[0]=0;
if( scrn->Title )
strncpy(buf,scrn->Title,40);
printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
buf,
scrn->LeftEdge,
scrn->TopEdge,
scrn->Width,
scrn->Height
);
for (window=scrn->FirstWindow; window; window=window->NextWindow) {
buf[0]=0;
if( window->Title )
strncpy(buf,window->Title,40);
printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
buf,
window->LeftEdge,
window->TopEdge,
window->Width,
window->Height
);
}
}
return 0;
}
if( o_nowindow || !Win )
return 20;
maxwidth = Win->WScreen->Width;
maxheight= Win->WScreen->Height;
if( options&1 )
x=Win->LeftEdge,y=Win->TopEdge,w=Win->MinWidth,h=Win->MinHeight;
if( options&2 ) x=y=0, w=maxwidth, h=maxheight;
if( options&4 ) WindowToFront(Win);
if( options&8 ) WindowToBack(Win);
if( options&16) ActivateWindow(Win);
if( ac >= 5) {
for(i=1; i<5; i++) {
arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
}
x=arg[1]; y=arg[2]; w=arg[3]; h=arg[4];
}
if( w!=-1 ) {
int i;
if ( x+w>maxwidth || y+h>maxheight ) {
ierror(NULL, 500);
return 20;
}
if( w<Win->MinWidth ) w=Win->MinWidth;
if( h<Win->MinHeight ) h=Win->MinHeight;
if( Win->LeftEdge!=0 || Win->TopEdge!=0 )
MoveWindow(Win, -Win->LeftEdge, -Win->TopEdge );
if( Win->Width!=w || Win->Height!=h )
SizeWindow(Win, w-Win->Width , h-Win->Height );
if( x || y )
MoveWindow(Win, x, y );
for( i=0; i<7; i++ ) {
if( Win->LeftEdge==x && Win->TopEdge==y &&
Win->Width ==w && Win->Height ==h )
break;
Delay(5);
}
} else
Delay(30); /* pause 1/2 sec. before trying to print */
printf("\014");
return 0;
}
static void
setsystemtime(struct DateStamp *ds)
{
struct timerequest tr;
long secs= ds->ds_Days*86400+ds->ds_Minute*60+ds->ds_Tick/TICKS_PER_SECOND;
if (OpenDevice(TIMERNAME, UNIT_VBLANK,(struct IORequest *)&tr, 0L)) {
fprintf(stderr,"Clock error: can't open timer device\n");
return;
}
tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
tr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
tr.tr_node.io_Message.mn_Node.ln_Name = NULL;
tr.tr_node.io_Message.mn_ReplyPort = NULL;
tr.tr_node.io_Command = TR_SETSYSTIME;
tr.tr_time.tv_secs = secs;
tr.tr_time.tv_micro = 0L;
if (DoIO ((struct IORequest *)&tr))
fprintf(stderr,"Clock error: can't talk to timer device\n");
CloseDevice ((struct IORequest *)&tr);
}
char tday[10];
char *
dates( struct DateStamp *dss )
{
static char timestr[40];
char tdate[10], ttime[10];
struct DateTime dt;
struct DateStamp *myds=&(dt.dat_Stamp);
dt.dat_Format=FORMAT_DOS;
dt.dat_StrDay=tday;
dt.dat_StrDate=tdate;
dt.dat_StrTime=ttime;
dt.dat_Flags=NULL;
myds->ds_Days=dss->ds_Days;
myds->ds_Minute=dss->ds_Minute;
myds->ds_Tick=dss->ds_Tick;
StamptoStr(&dt);
sprintf(timestr,"%s %s\n",tdate,ttime);
timestr[18]=0; /* protection against bad timestamped files */
return timestr;
}
int
do_date( void )
{
static long stopwatch;
struct DateStamp dss;
struct DateTime dt;
long time;
int i=1;
dt.dat_Format=FORMAT_DOS;
if (ac==1) {
DateStamp(&dss);
time=dss.ds_Minute*6000+2*dss.ds_Tick; /* 2 = 100/TickPerSec */
if( options & 1 )
stopwatch=time;
else if( options&2 )
printf( "%d.%02d\n",(time-stopwatch)/100,(time-stopwatch)%100);
else
printf("%s %s\n",tday,dates(&dss));
} else {
DateStamp(&dt.dat_Stamp);
for ( ; i<ac; i++) {
dt.dat_StrDate=NULL;
dt.dat_StrTime=NULL;
dt.dat_Flags=DTF_FUTURE;
if (index(av[i],':')) dt.dat_StrTime=av[i];
else dt.dat_StrDate=av[i];
if (StrtoStamp(&dt)) ierror(av[i],500);
}
setsystemtime( & (dt.dat_Stamp) );
}
return 0;
}